#include <iostream>
#include <fstream>
#include <cmath>
#include <stdlib.h>

#include "raster.hpp"

Raster::Raster(int width, int height)
{
	width_ = width;
	height_ = height;
	data_ = new Color[width * height];
}

Raster::~Raster()
{
	delete [] data_;
}

void Raster::setPixel(int x, int y, const Color& c)
{
	if(x < 0 || x >= width_ || y < 0 || y > height_)
		throw runtime_error("Raster::setPixel pixel coords out of bounds");
	*(data_ + x + y * width_) = c;
}

Color& Raster::getPixel(int x, int y) const
{
	if(x < 0 || x >= width_ || y < 0 || y > height_)
		throw runtime_error("Raster::getPixel pixel coords out of bounds");
	return *(data_ + x + y * width_);
}

int Raster::getWidth() const
{
	return width_;
}

int Raster::getHeight() const
{
	return height_;
}

void Raster::writePPM(const char* filename) const
{
	ofstream file = ofstream(filename, ios_base::out | ios_base::trunc);
	file << "P3 " << width_ << " " << height_ << " 255" << endl;
	int size = width_ * height_;
	for(int i = 0; i < size; i++)
	{
		file << ceil(clamp((data_ + i)->getR()) * 254 + (double(rand()) / (RAND_MAX * 1.2))) << " ";
		file << ceil(clamp((data_ + i)->getG()) * 254 + (double(rand()) / (RAND_MAX * 1.2))) << " ";
		file << ceil(clamp((data_ + i)->getB()) * 254 + (double(rand()) / (RAND_MAX * 1.2))) << endl;
	}
	file.close();
}

double Raster::clamp(double a)
{
	if(a >= 0.0 && a <= 1.0)
		return a;
	if(a < 0.0)
		return 0.0;
	return 1.0;
}
